package com.lingx.web.core;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;

import org.springframework.jdbc.core.JdbcTemplate;

import com.lingx.service.LingxService;
import com.lingx.utils.TokenUtils;
import com.lingx.utils.Utils;
import com.lingx.web.LingxApp;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.FileUpload;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.util.CharsetUtil;

public class FileUploadRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

	@Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws Exception {
		LingxService lingx=LingxApp.SPRINGCONTEXT.getBean(LingxService.class);
		try {
			String pathRoot=lingx.getConfigValue("lingx.file.save.path", "");
			String allowed=lingx.getConfigValue("lingx.upload.allowed", "png,jpg,jpeg,gif,bpmn,zip,doc,docx,xls,xlsx,rar,lwf,txt,pdf");
			if(Utils.isNull(pathRoot)) {
				pathRoot=System.getProperty("user.dir")+"/files/";
			}
			System.out.println("Upload:"+pathRoot);
			String token=null;
			String errMsg="";
			{
				HttpPostRequestDecoder httpDecoder = new HttpPostRequestDecoder(fullHttpRequest);
			    List<InterfaceHttpData> interfaceHttpDataList = httpDecoder.getBodyHttpDatas();
			    for (InterfaceHttpData data : interfaceHttpDataList) {
			        if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
			             if(Utils.isNull(token)) {
			            	errMsg="上传失败,token为空";
			            	System.out.println(errMsg);
			             	break;
			             }
			             if(!TokenUtils.verifyToken(token)) {
			            	 errMsg="上传失败,token无效";
			             	System.out.println(errMsg);
			              	break;
			             }
			            FileUpload fileUpload = (FileUpload) data;
			            if(allowed.contains(this.getSuffix(fileUpload.getFilename()))) {
			            	 String path=saveFile(fileUpload.getFilename(),fileUpload.get().length,token,pathRoot);
			            	 FileOutputStream fileOutputStream2=null;
			                 try( FileOutputStream fileOutputStream = new FileOutputStream(pathRoot+path) ) {
			                     fileOutputStream.write(fileUpload.get());
			                     fileOutputStream.flush();
			                     fileOutputStream2=fileOutputStream;
			                 }finally {
			                	 if(fileOutputStream2!=null) {
			                		 fileOutputStream2.close();
			                	 }
			                	 
			                 }
			            }else {
			            	errMsg="上传失败,不允许上传的文件格式";
			             	System.out.println(errMsg);
			            }
			           
			        }
			        //如果数据类型为参数类型，则保存到body对象中
			        if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute){
			            Attribute attribute = (Attribute) data;
			            token=attribute.getValue();
			            System.out.println(attribute.getName() + ":" + attribute.getValue());
			        }
			    }
			    httpDecoder.destroy();
			    interfaceHttpDataList.clear();
			    interfaceHttpDataList=null;
			}
			FullHttpResponse response = new DefaultFullHttpResponse(
			        io.netty.handler.codec.http.HttpVersion.HTTP_1_1,
			        HttpResponseStatus.OK,
			        Unpooled.copiedBuffer(errMsg, CharsetUtil.UTF_8));
			response.headers().set("Access-Control-Allow-Origin", "*");
			response.headers().add("Access-Control-Allow-Methods", "GET,POST");
			response.headers().set("Content-Type", "application/json; charset=UTF-8");
			response.headers().set("Content-Length", response.content().readableBytes());

			channelHandlerContext.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
	
	public String saveFile(String filename,long length,String token,String pathRoot) {
		String t_ext=this.getSuffix(filename);
		
		String path="upload/"+getDate() + System.currentTimeMillis() + "." + t_ext;
		try {
			File dir=new File(pathRoot+"upload/"+getDate());
			if(!dir.exists())dir.mkdirs();
			String userId=TokenUtils.getTokenDataUserId(token);
			//System.out.println(path);
			//System.out.println(length);
			//System.out.println(userId);
			//System.out.println(filename);
			JdbcTemplate jdbc=LingxApp.SPRINGCONTEXT.getBean(JdbcTemplate.class);
			jdbc.update("insert into tlingx_file(id,name,length,user_id,ts) values(?,?,?,?,?)",path,filename,length,userId,Utils.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return path;
	}

	public String getSuffix(String name){
		String suffix="";
		if(name.indexOf(".")>0){
			suffix=name.substring(name.lastIndexOf(".")+1);
		}
		return suffix;
	}
	public static String getDate() {
		String dateTime = MessageFormat.format("{0,date,yyyy/MM/dd/}",
				new Object[] { new java.sql.Date(System.currentTimeMillis()) });
		return dateTime;

	}
}

